
package biblio.util.interfaces;


import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;


/**
 * Interface used to defined operations on Patterns of regular expressions container.
 *
 * 2011-10-15
 * @author mephisto
 */
public interface RegexContainer
{
    /**
     * Initializes container by compiling all regular expressions given in map.
     */
    void init(Map<String,String> regexMap);

    /**
     * Removes all of the mappings from this container (optional operation).
     */
    void clear();

    /**
     * Returns true if this container contains a mapping for the specified regexName.
     * 
     * @param regexName the regexName whose presence in this container is to be tested
     * @return {@code true} if this container contains a mapping for the specified
     * regexName.
     */
    boolean containsRegexName(String regexName);

    /**
     * Returns {@code true} if this container maps one or more regexName to the
     * specified regex.
     *
     * @param regex regex whose presence in this container is to be tested
     * @return {@code true} if this container maps one or more regexName to the
     *         specified regex
     */
    boolean containsRegex(String regex);

    /**
     * Returns the pattern to which the specified regexName is mapped,
     * or {@code null} if this container contains no mapping for the regexName.
     *
     * <p>More formally, if this container contains a mapping from a regexName
     * {@code k} to a value {@code v} such that {@code (regexName==null ? k==null :
     * regexName.equals(k))}, then this method returns {@code v}; otherwise
     * it returns {@code null}.  (There can be at most one such mapping.)
     *
     * <p>A return value of {@code null} does not <i>necessarily</i>
     * indicate that the container contains no mapping for the key; it's also
     * possible that the container explicitly maps the key to {@code null}.
     * The {@link #containsRegex containsRegex} operation may be used to
     * distinguish these two cases.
     *
     * @param regexName the regexName to set
     * @return the pattern to which the specified regexName is mapped,
     * or {@code null} if this container contains no mapping for the regexName.
     * @see #add(String, String)
     */
    Pattern getPattern(String regexName);
    
    /**
     * Returns the pattern to which the specified regexName is mapped,
     * or {@code null} if this container contains no mapping for the regexName.
     *
     * <p>More formally, if this container contains a mapping from a regexName
     * {@code k} to a value {@code v} such that {@code (regexName==null ? k==null :
     * regexName.equals(k))}, then this method returns {@code v}; otherwise
     * it returns {@code null}.  (There can be at most one such mapping.)
     *
     * <p>A return value of {@code null} does not <i>necessarily</i>
     * indicate that the container contains no mapping for the key; it's also
     * possible that the container explicitly maps the key to {@code null}.
     * The {@link #containsRegex containsRegex} operation may be used to
     * distinguish these two cases.
     *
     * @param regexName the regexName to set
     * @return the regex to which the specified regexName is mapped,
     * or {@code null} if this container contains no mapping for the regexName.
     */
    String getRegex(String regexName);

    /**
     * Returns {@code true} if this container contains no regexName-pattern mappings.
     *
     * @return {@code true} if this container contains no regexName-pattern mappings
     */
    boolean isEmpty();

    /**
     * Returns a {@link java.util.Set} view of the regeNames contained in this container.
     *
     * The set is backed by the container, so changes to the container are
     * reflected in the set, and vice-versa.  If the container is modified
     * while an iteration over the set is in progress (except through
     * the iterator's own {@code remove} operation), the results of
     * the iteration are undefined.  The set supports element removal,
     * which removes the corresponding mapping from the container, via the
     * {@code Iterator.remove}, {@code Set.remove},
     * {@code removeAll}, {@code retainAll}, and {@code clear}
     * operations.  It does not support the {@code add}> or {@code addAll}
     * operations.
     *
     * @return a Set view of the keys contained in this container.
     */
    Set<String> regexNameSet();

    /**
     * Associates the specified regex with the specified regexName in this container.
     * If the container previously contained a mapping for the regexName, the old
     * regex is replaced.
     *
     * @param regexName regexName with which the specified regex is to be associated
     * @param regex regex to be associated with the specified regexName
     * @return the previous value associated with {@code regexName}, or
     *         {@code null} if there was no mapping for {@code regexName}.
     *         (A {@code null} return can also indicate that the container
     *         previously associated {@code null} with {@code regexName}.)
     */
    Pattern add(String regexName, String regex);

    /**
     * Removes the mapping for the specified regexName from this container if present.
     *
     * @param  regexName regexName whose mapping is to be removed from the container
     * @return the previous value associated with {@code regexName}, or
     *         {@code null} if there was no mapping for {@code regexName}.
     *         (A {@code null} return can also indicate that the container
     *         previously associated {@code null} with {@code regexName}.)
     */
    Pattern remove(String regexName);

    /**
     * Returns the number of regexName-regex mappings in this container.
     *
     * @return the number of regexName-regex mappings in this container
     */
    int	size();

     /**
      * Returns a {@link java.util.Collection} view of the regex contained in
      * this container.
      *
      * The collection is backed by the container, so changes to the container
      * are reflected in the collection, and vice-versa.  If the container is
      * modified while an iteration over the collection is in progress
      * (except through the iterator's own {@code remove} operation),
      * the results of the iteration are undefined.  The collection
      * supports element removal, which removes the corresponding
      * mapping from the container, via the {@code Iterator.remove},
      * {@code Collection.remove}, {@code removeAll},
      * {@code retainAll} and {@code clear} operations.  It does not
      * support the {@code add} or {@code addAll} operations.
      *
      * @return a {@link java.util.Collection} view of the regex contained in
      * this container.
     */
    Collection<Pattern> getPatterns();
}
